
from inspect import signature as sig
import ossl, xml.etree.ElementTree as ET

XE = type('XE', (ET.Element,), { "document": None, "parent": None, \
    "__init__": lambda self, *args: ET.Element.__init__(self, *args),
    "_prev": None, "_next": None, "_parent": None, "_doc": None,
    "doc": lambda self: self._parent if type(self._parent).__name__ == "ElementTree" else self._parent.doc(),
    "parent": lambda self: None if type(self._parent).__name__ == "ElementTree" else self._parent,
    "index": lambda self: [self] if type(self._parent).__name__ == "ElementTree" else self._parent.index() + [self],
     })

class TreeBuilder(ET.TreeBuilder):
    def __init__(self):
        try:
            return ET.TreeBuilder.__init__(self, element_factory=XE)
        except Exception as e:
            print(e, e.with_traceback(e.__traceback__))
            return None
        # dummy comment

    def start(self, tag, attrib):   # Called for each opening tag.
        try:
            return ET.TreeBuilder.start(self, tag, attrib)
        except Exception as e:
            print(e, e.with_traceback(e.__traceback__))
            return None

    def end(self, tag):             # Called for each closing tag.
        try:
            r = ET.TreeBuilder.end(self, tag)
            prev = None
            for c in r:
                c._parent = r
                c._prev = prev
                if c._prev is not None: c._prev._next = r
                prev = r
            return r
        except Exception as e:
            print(e, e.with_traceback(e.__traceback__))
            return None

    def data(self, data):
        return ET.TreeBuilder.data(self, data)

    def close(self):    # Called when all data has been parsed.
        r = ET.TreeBuilder.close(self)
        return r

def adjust_elements(doc):
    doc.getroot()._parent = doc

def from_string(msg):
    try:
        doc = ET.ElementTree()
        doc._setroot(ET.fromstring(msg, parser=ET.XMLParser(target=TreeBuilder())))
        adjust_elements(doc)
        return doc
    except Exception as e:
        print(e)
        return None

def from_file(href): # ossl.__path__[0] + "\\addon_contents.xml"
    try:
        import ossl, xml.etree.ElementTree as ET
        doc = ET.parse(href, parser=ET.XMLParser(target=TreeBuilder()))
        adjust_elements(doc)
        return doc
    except Exception as e:
        print(e)
        return None
    
def next(it):
    try: return it.__next__()
    except: return None

def xxx():
    doc = xml.from_string(msg)    
    elem = doc.find("./dir//file")
    elem = doc.parent(elem) 

    doc_local = xml.from_file(util.path("addon_contents.xml"))
    root = doc_local._root
    for file in doc_local.findall(".//file[@dt='2021-08-13 05:59:16']"):
        print(file.get("name"), file.items())
        p = doc_local.parent(file)
        print(p.tag, p.items())

    root = doc.getroot()
    print("############ ", root.items())
    #print("verifying addon", doc.tag, doc.get("name"), doc.get("dt"), "\n", dir(doc))
    doc_local = ET.parse(ossl.__path__[0] + "\\addon_contents.xml")
    print("############ ", type(doc_local))
#    print("     with addon", dir(doc_local))

    root = doc_local._root

#    print("     with addon", root.tag, root.get("name"), root.get("dt"))

    parent_map = {c: p for p in root.iter() for c in p}

    for file in doc_local.findall(".//file[@dt='2021-08-13 05:59:16']"):
#        print(file.get("name"), file.items(), file.find(".."))
        p = parent_map.get(file)
#        print(p.tag, p.items())

    #print(ET.tostring(root))

if __name__ == "__main__":
    import ossl.util as util
    print("\n")
    util.reset_addon()
